/**
  * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved.
  * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
  * following conditions are met:
  * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
  * disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
  * following disclaimer in the documentation and/or other materials provided with the distribution.
  * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote
  * products derived from this software without specific prior written permission.
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  * @file      softserial_sample.c
  * @author    MCU Application Team
  * @brief     Softserial sample code
  * @details   This file provides firmware functions to manage the following
  *            functionalities of the common function sample.
  *             + Softserial sample functions.
  */

/* Includes ------------------------------------------------------------------ */
#include "softserial_sample.h"

/* Private macro ------------------------------------------------------------- */
#define BOARD_SOFTSERIAL_SAMPLE_BAUDRATE 1200
#define BOARD_SOFTSERIAL_SAMPLE_DATALENGTH 8

/* Private variables --------------------------------------------------------- */
static TIMER_Handle g_timer1;
static TIMER_Handle g_timer2;
static GPIO_Handle g_gpio0;
static GPIO_Handle g_gpio1;

static void TIMER1_Init(void);
static void TIMER2_Init(void);
static void GPIO0_Init(void);
static void GPIO1_Init(void);

/**
  * @brief Timer initialization function, it is automatically generated by the code generation tool.
  */
static void TIMER1_Init(void)
{
    g_timer1.baseAddress = TIMER1;
    g_timer1.load = 1; /* Set timer value immediately */
    g_timer1.bgLoad = 1;
    g_timer1.mode = TIMER_MODE_RUN_PERIODIC; /* Run in period mode */
    g_timer1.prescaler = 0; /* don't frequency division */
    g_timer1.interruptEn = 1; /* trigger interrupt enable */
    g_timer1.size = 1; /* 1 for 32bit, 0 for 16bit */
    g_timer1.irqNum = IRQ_TIMER1;
    IRQ_SetPriority(g_timer1.irqNum, 1); /* set timer0 interrupt priority to 1, 1~7 */
    IRQ_EnableN(g_timer1.irqNum); /* timer interrupt enable */
    HAL_TIMER_Init(&g_timer1);
}

/**
  * @brief Timer initialization function, it is automatically generated by the code generation tool.
  */
static void TIMER2_Init(void)
{
    g_timer2.baseAddress = TIMER2;
    g_timer2.load = 1; /* Set timer value immediately */
    g_timer2.bgLoad = 1;
    g_timer2.mode = TIMER_MODE_RUN_PERIODIC; /* Run in period mode */
    g_timer2.prescaler = 0; /* don't frequency division */
    g_timer2.interruptEn = 1; /* trigger interrupt enable */
    g_timer2.size = 1; /* 1 for 32bit, 0 for 16bit */
    g_timer2.irqNum = IRQ_TIMER2;
    IRQ_SetPriority(g_timer2.irqNum, 1); /* set timer0 interrupt priority to 1, 1~7 */
    IRQ_EnableN(g_timer2.irqNum); /* timer interrupt enable */
    HAL_TIMER_Init(&g_timer2);
}

/**
  * @brief GPIO initialization function, it is automatically generated by the code generation tool.
  */
static void GPIO0_Init(void)
{
    g_gpio0.baseAddress = GPIO0;
    g_gpio0.dir = GPIO_OUTPUT_MODE;
    g_gpio0.value = GPIO_HIGH_LEVEL;
    g_gpio0.interruptMode = GPIO_INT_TYPE_NONE;
    g_gpio0.pins = GPIO_PIN_0;
    HAL_GPIO_Init(&g_gpio0);
}

/**
  * @brief GPIO initialization function, it is automatically generated by the code generation tool.
  */
static void GPIO1_Init(void)
{
    g_gpio1.baseAddress = GPIO3;
    g_gpio1.dir = GPIO_OUTPUT_MODE;
    g_gpio1.value = GPIO_HIGH_LEVEL;
    g_gpio1.interruptMode = GPIO_INT_TYPE_NONE;
    g_gpio1.pins = GPIO_PIN_0;
    HAL_GPIO_Init(&g_gpio1);
}

/**
  * @brief Soft serial port loopback example.
  * @return int Execution result.
  */
int BOARD_SOFTSERIAL_Sample(void)
{
    IRQ_Enable();
    IRQ_Init();

    TIMER1_Init();
    GPIO0_Init();
    TIMER2_Init();
    GPIO1_Init();

    BOARD_SOFTSERIAL_TxInit(&g_gpio0, &g_timer1, BOARD_SOFTSERIAL_SAMPLE_BAUDRATE, BOARD_SOFTSERIAL_SAMPLE_DATALENGTH,
        BOARD_SOFTSERIAL_PARITY_NONE, BOARD_SOFTSERIAL_STOPBITS_ONE);
    BOARD_SOFTSERIAL_RxInit(&g_gpio1, &g_timer2, BOARD_SOFTSERIAL_SAMPLE_BAUDRATE, BOARD_SOFTSERIAL_SAMPLE_DATALENGTH,
        BOARD_SOFTSERIAL_PARITY_NONE, BOARD_SOFTSERIAL_STOPBITS_ONE);

    unsigned char tmp;
    while (1) {
        if (BOARD_SOFTSERIAL_GetChar(&tmp) == BOARD_SOFTSERIAL_OK) {
            BOARD_SOFTSERIAL_PrintCh(tmp);
        }
    }
    return BASE_STATUS_OK;
}